package com.eaero.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.eaero.CommonResp;
import cn.hutool.core.util.StrUtil;
import com.eaero.controller.tool.pojo.*;
import com.eaero.entity.TraceExceptionFeelBackRecode;
import com.eaero.entity.TraceJobCard;
import com.eaero.entity.TraceSyncIssueReturnRecode;
import com.eaero.entity.TraceTool;
import com.eaero.mapper.TraceJobCardMapper;
import com.eaero.mapper.TraceToolMapper;
import com.eaero.service.ITraceExceptionFeelBackRecodeService;
import com.eaero.service.ITraceSyncIssueReturnRecodeService;
import com.eaero.service.ITraceToolService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.eaero.util.IdGenUtils;
import com.eaero.vo.BindRFID;
import com.eaero.vo.ExceptionFeelBack;
import com.eaero.vo.ExceptionFeelBackRequest;
import com.google.common.collect.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author zb
 * @since 2023-03-14
 */
@Service
public class TraceToolServiceImpl extends ServiceImpl<TraceToolMapper, TraceTool> implements ITraceToolService {

    @Autowired
    TraceJobCardMapper traceJobCardMapper;
    @Autowired
    ITraceSyncIssueReturnRecodeService traceSyncIssueReturnRecodeService;
    @Autowired
    ITraceExceptionFeelBackRecodeService traceExceptionFeelBackRecodeService;

    @Override
    public CommonResp exceptionFeelBack(ExceptionFeelBackRequest request) {
        for (ExceptionFeelBack exceptionFeelBack : request.getExceptionFeelBack()) {
            update(Wrappers.<TraceTool>lambdaUpdate()
                    .set(TraceTool::getTlFlag, exceptionFeelBack.getFbDesc())
                    .eq(TraceTool::getPartno, exceptionFeelBack.getTlPn())
                    .eq(TraceTool::getTrno, exceptionFeelBack.getTlTr()));
        }
        if (StrUtil.equals(request.getOrigin(), "A")) {
            List<TraceExceptionFeelBackRecode> recodeList = request.getExceptionFeelBack().stream().map(exceptionFeelBack -> {
                TraceExceptionFeelBackRecode recode = new TraceExceptionFeelBackRecode();
                recode.setFbBy(request.getFbBy());
                recode.setOrigin(request.getOrigin());
                BeanUtil.copyProperties(exceptionFeelBack, recode);
                return recode;
            }).collect(Collectors.toList());
            traceExceptionFeelBackRecodeService.saveBatch(recodeList, 500);
        }
        return CommonResp.buildSucsDataListMsg(null, "反馈成功！");
    }

    @Override
    public List<TraceTool> getToolInfo(String rfidId, String partno, String trno, String partdescr, String barcode, String searchKeyTl, String warehouse) {
        ArrayList<String> rfidIds = Lists.newArrayList();
        if (StrUtil.isNotBlank(rfidId)) {
            rfidIds.addAll(StrUtil.split(rfidId, "."));
        }
        List<TraceTool> re = this.list(Wrappers.<TraceTool>lambdaQuery()
                .select(TraceTool::getPartno, TraceTool::getTrno, TraceTool::getParent,
                        TraceTool::getParentTrno, TraceTool::getParentPartno,
                        TraceTool::getBarcode, TraceTool::getRid,
                        TraceTool::getRfidId, TraceTool::getStandByPn,
                        TraceTool::getStoresloc, TraceTool::getWarehouse,
                        TraceTool::getWhseDesc, TraceTool::getCatalogueType,
                        TraceTool::getChildNum, TraceTool::getSearchKeyTl,
                        TraceTool::getMeasuringNo, TraceTool::getUnitofmeas,
                        TraceTool::getImgFlag, TraceTool::getTlFlag,
                        TraceTool::getIssueRemind, TraceTool::getPartdescr
                )
                .like(StrUtil.isNotBlank(trno), TraceTool::getTrno, trno)
                .like(StrUtil.isNotBlank(partno), TraceTool::getPartno, partno)
                .like(StrUtil.isNotBlank(partdescr), TraceTool::getPartdescr, partdescr)
                .eq(StrUtil.isNotBlank(barcode), TraceTool::getBarcode, barcode)
                .like(StrUtil.isNotBlank(searchKeyTl), TraceTool::getSearchKeyTl, searchKeyTl)
                .eq(StrUtil.isNotBlank(warehouse), TraceTool::getWarehouse, warehouse)
                .eq(TraceTool::getScrap, "0")
                .in(CollUtil.isNotEmpty(rfidIds), TraceTool::getRfidId, rfidIds)
        );
        return re;
    }

    @Override
    public List<TraceTool> getInventoryInfo(String rid, String rfidId, String partno, String trno, String partdescr, String barcode, String searchKeyTl, String warehouse, String storesloc) {
        ArrayList<String> rfidIds = Lists.newArrayList();
        if (StrUtil.isNotBlank(rfidId)) {
            rfidIds.addAll(StrUtil.split(rfidId, "."));
        }
        List<TraceTool> re = this.list(Wrappers.<TraceTool>lambdaQuery()
                .select(TraceTool::getPartno, TraceTool::getTrno, TraceTool::getParent,
                        TraceTool::getParentTrno, TraceTool::getParentPartno,
                        TraceTool::getBarcode, TraceTool::getRid,
                        TraceTool::getRfidId, TraceTool::getStandByPn,
                        TraceTool::getStoresloc, TraceTool::getWarehouse,
                        TraceTool::getWhseDesc, TraceTool::getCatalogueType,
                        TraceTool::getChildNum, TraceTool::getSearchKeyTl,
                        TraceTool::getMeasuringNo, TraceTool::getUnitofmeas,
                        TraceTool::getImgFlag, TraceTool::getTlFlag,
                        TraceTool::getIssueRemind, TraceTool::getPartdescr,
                        TraceTool::getOnhand, TraceTool::getTlStatus
                )
                .eq(StrUtil.isNotBlank(rid), TraceTool::getRid, rid)
                .in(CollUtil.isNotEmpty(rfidIds), TraceTool::getRfidId, rfidIds)
                .like(StrUtil.isNotBlank(trno), TraceTool::getTrno, trno)
                .like(StrUtil.isNotBlank(partno), TraceTool::getPartno, partno)
                .like(StrUtil.isNotBlank(partdescr), TraceTool::getPartdescr, partdescr)
                .eq(StrUtil.isNotBlank(barcode), TraceTool::getBarcode, barcode)
                .like(StrUtil.isNotBlank(searchKeyTl), TraceTool::getSearchKeyTl, searchKeyTl)
                .eq(StrUtil.isNotBlank(warehouse), TraceTool::getWarehouse, warehouse)
                .eq(StrUtil.isNotBlank(storesloc), TraceTool::getStoresloc, storesloc)
                .eq(TraceTool::getScrap, "0")
        );
        return re;
    }

    @Override
    public CommonResp issueTool(IssueRequest request) {
        List<ToolIssue> toolIssue = request.getToolIssue();
        List<String> ridList = toolIssue.stream().map(ToolIssue::getRid).distinct().collect(Collectors.toList());
        long countCheck = this.count(Wrappers.<TraceTool>lambdaQuery()
                .in(TraceTool::getRid, ridList)
                .eq(TraceTool::getTlStatus, "借出")
        );
        if (countCheck > 0) {
            return CommonResp.buildFailMsg("件号 Partno 刻号 Trno 处于借出状态,无法发料!");
        }

        long countCheckStock = this.count(Wrappers.<TraceTool>lambdaQuery()
                .in(TraceTool::getRid, ridList)
                .lt(TraceTool::getOnhand, 1)
        );
        if (countCheckStock > 0) {
            return CommonResp.buildFailMsg("件号 Partno 刻号 Trno 库存异常，请核对数据后发料！");
        }
        for (ToolIssue tool : toolIssue) {
            this.update(Wrappers.<TraceTool>lambdaUpdate()
                    .set(TraceTool::getTlStatus, "借出")
                    .set(TraceTool::getJcWo, request.getJcWo())
                    .set(TraceTool::getAcno, request.getReg())
                    .set(TraceTool::getOpRemark, tool.getOpRemark())
                    .set(TraceTool::getIssueTo, request.getUserCode())
                    .set(TraceTool::getIssueDate, DateUtil.now())
                    .set(TraceTool::getEmpCode, "EmpCode001")
                    .set(TraceTool::getIssueRid, tool.getRid())
                    .eq(TraceTool::getRid, tool.getRid())
            );
        }
        if (StrUtil.equals(request.getOrigin(), "A")) {
            List<TraceSyncIssueReturnRecode> recodeDetails = toolIssue.stream().map(item -> {
                TraceSyncIssueReturnRecode recodeDetail = new TraceSyncIssueReturnRecode();
                recodeDetail.setId(IdGenUtils.genId());
                recodeDetail.setRecodeType("1");
                recodeDetail.setOrigin(request.getOrigin());
                recodeDetail.setDeliver(request.getDeliver());
                recodeDetail.setUserCode(request.getUserCode());
                recodeDetail.setEmpCode(request.getEmpCode());
                recodeDetail.setOnlineFlag(request.getOnlineFlag());
                recodeDetail.setReg(request.getReg());
                recodeDetail.setJcWo(request.getJcWo());
                BeanUtil.copyProperties(item, recodeDetail);
                return recodeDetail;
            }).collect(Collectors.toList());
            traceSyncIssueReturnRecodeService.saveBatch(recodeDetails, 500);
        }
        return CommonResp.buildSuccessMsg("发料成功！[" + System.currentTimeMillis() + "]");
    }

    @Override
    public CommonResp returnTool(ReturnRequest request) {
        List<ToolReturn> toolReturn = request.getToolReturn();
        List<String> ridList = toolReturn.stream().map(ToolReturn::getRid).distinct().collect(Collectors.toList());
        long countCheck = this.count(Wrappers.<TraceTool>lambdaQuery()
                .in(TraceTool::getRid, ridList)
                .eq(TraceTool::getTlStatus, "在库")
        );
        if (countCheck > 0) {
            return CommonResp.buildFailMsg("件号 Partn 刻号 Trno 处于未借出状态,无法退料!");
        }
        boolean re = this.update(Wrappers.<TraceTool>lambdaUpdate()
                .set(TraceTool::getTlStatus, "在库")
                .in(TraceTool::getRid, ridList)
        );
        if (StrUtil.equals(request.getOrigin(), "A")) {
            List<TraceSyncIssueReturnRecode> recodeDetails = toolReturn.stream().map(item -> {
                TraceSyncIssueReturnRecode recodeDetail = new TraceSyncIssueReturnRecode();
                recodeDetail.setId(IdGenUtils.genId());
                recodeDetail.setRecodeType("2");
                recodeDetail.setOrigin(request.getOrigin());
                recodeDetail.setUserCode(request.getUserCode());
                recodeDetail.setEmpCode(request.getEmpCode());
                BeanUtil.copyProperties(item, recodeDetail);
                return recodeDetail;
            }).collect(Collectors.toList());
            traceSyncIssueReturnRecodeService.saveBatch(recodeDetails, 500);
        }
        if (re) {
            return CommonResp.buildSuccessMsg("退料成功！[" + System.currentTimeMillis() + "]");
        }
        return CommonResp.buildFailMsg("退料失败");
    }

    @Override
    public List<TraceJobCard> GetWorkorderno(String workorderno) {
        return traceJobCardMapper.selectList(Wrappers.<TraceJobCard>lambdaQuery()
                .select(TraceJobCard::getWorkorderno, TraceJobCard::getJobcard, TraceJobCard::getReg)
                .eq(TraceJobCard::getWorkorderno, workorderno));
    }

    @Override
    public List<TraceTool> GetLoanToolsAll(String issueTo, String rfidId, String partno, String trno,

            String partdescr, String barcode, String issueDate, String warehouse, String storesloc, String issueRid, String jcWo, String acno, String tpNo, String searchKeyTl) {
        LocalDateTime date = null;
        if (StrUtil.isNotBlank(issueDate)){
            date = LocalDateTimeUtil.parse(issueDate, DatePattern.NORM_DATE_PATTERN);
        }
        List<TraceTool> re = this.list(Wrappers.<TraceTool>lambdaQuery()
                .select(
                        TraceTool::getIssueRemind,TraceTool::getPartno,
                        TraceTool::getParent,TraceTool::getParentPartno,
                        TraceTool::getTrno,TraceTool::getWarehouse,
                        TraceTool::getIssueRid,TraceTool::getParentTrno,
                        TraceTool::getMeasuringNo,TraceTool::getRid,
                        TraceTool::getPartdescr,TraceTool::getStandByPn,
                        TraceTool::getStoresloc,TraceTool::getOnhand,
                        TraceTool::getTlFlag,TraceTool::getImgFlag

                )
                .eq(StrUtil.isNotBlank(rfidId), TraceTool::getRfidId, rfidId)
                .like(StrUtil.isNotBlank(trno), TraceTool::getTrno, trno)
                .like(StrUtil.isNotBlank(partno), TraceTool::getPartno, partno)
                .like(StrUtil.isNotBlank(partdescr), TraceTool::getPartdescr, partdescr)
                .like(StrUtil.isNotBlank(searchKeyTl), TraceTool::getSearchKeyTl, searchKeyTl)
                .eq(StrUtil.isNotBlank(barcode), TraceTool::getBarcode, barcode)
                .like(StrUtil.isNotBlank(issueTo), TraceTool::getIssueTo, issueTo)
                .eq(StrUtil.isNotBlank(warehouse), TraceTool::getWarehouse, warehouse)
                .eq(StrUtil.isNotBlank(storesloc), TraceTool::getStoresloc, storesloc)
                .eq(StrUtil.isNotBlank(acno), TraceTool::getAcno, acno)
                .eq(StrUtil.isNotBlank(jcWo), TraceTool::getJcWo, jcWo)
                .eq(StrUtil.isNotBlank(issueRid), TraceTool::getIssueRid, issueRid)
                .gt(date != null, TraceTool::getIssueDate, date)
                .eq(TraceTool::getTlStatus, "借出")
                .eq(TraceTool::getScrap, "0")

        );
        return re;
    }

    @Override
    public CommonResp bindRFID(BindRFID request) {
        TraceTool tool = getOne(Wrappers.<TraceTool>lambdaQuery().eq(TraceTool::getRid, request.getRid()));
        if (ObjectUtil.isEmpty(tool)) {
            return CommonResp.buildFailMsg("件号信息不存在！");
        }
        if (StrUtil.isNotEmpty(tool.getRfidId())) {
            return CommonResp.buildFailMsg("该件号已存在 RFID，请先解绑！");
        }
       update(Wrappers.<TraceTool>lambdaUpdate().set(TraceTool::getRfidId, request.getRfidId())
                .eq(TraceTool::getRid, request.getRid()));
        return CommonResp.buildSuccessMsg("标签绑定成功！");
    }

    @Override
    public CommonResp unBindRFID(BindRFID request) {
        TraceTool tool = getOne(Wrappers.<TraceTool>lambdaQuery().eq(TraceTool::getRid, request.getRid()));
        if (ObjectUtil.isEmpty(tool)) {
            return CommonResp.buildFailMsg("件号信息不存在！");
        }

        boolean update = update(Wrappers.<TraceTool>lambdaUpdate()
                .set(TraceTool::getRfidId, StrUtil.EMPTY)
                .eq(TraceTool::getRid, request.getRid()));

        return CommonResp.buildSuccessMsg("标签解绑成功！");
    }

    @Override
    public void doTlDiscard(List<String> trno) {
        update(Wrappers.<TraceTool>lambdaUpdate().set(TraceTool::getScrap, "1").in(TraceTool::getTrno, trno));
    }

    @Override
    public List<ToolDetail> getTooldetail(String rid, String trno, String partno) {
        List<ToolDetail> ret = new ArrayList<>();
        TraceTool tool = getOne(Wrappers.<TraceTool>lambdaQuery()
                .eq(TraceTool::getTrno, trno)
                .eq(TraceTool::getPartno, partno)
        );
        if (tool != null) {
            List<TraceTool> toolList = this.list(Wrappers.<TraceTool>lambdaQuery()
                    .eq(TraceTool::getParent, tool.getRid())
            );
           ret = toolList.stream().map(traceTool -> {
                ToolDetail toolDetail = new ToolDetail();
                toolDetail.setStation("CAN");
                toolDetail.setIssueRemind(traceTool.getIssueRemind());
                toolDetail.setPartno(traceTool.getPartno());
                toolDetail.setParenetrid(tool.getRid());
                toolDetail.setPartentPartno(traceTool.getParentPartno());
                toolDetail.setAlternatePartno("");
                toolDetail.setTrno(traceTool.getTrno());
                toolDetail.setWarehouse(traceTool.getWarehouse());
                toolDetail.setIssueRid(traceTool.getIssueRid());
                toolDetail.setParentTrno(traceTool.getParentTrno());
                toolDetail.setCommentText("仓库描述");
                toolDetail.setMeasuringNo(traceTool.getMeasuringNo());
                toolDetail.setRid(traceTool.getRid());
                toolDetail.setPartdescr(traceTool.getPartdescr());
                toolDetail.setStandByPn(traceTool.getStandByPn());
                //可发标记 Y
                toolDetail.setFlagIssue(traceTool.getFlagIssue());
                toolDetail.setStoresloc(traceTool.getStoresloc());
                toolDetail.setOnhand(traceTool.getOnhand().toString());
                toolDetail.setTlFlag(traceTool.getTlFlag());
               toolDetail.setTlStatus(traceTool.getTlStatus());
                toolDetail.setImgFlag(traceTool.getImgFlag());
                return toolDetail;
            }).collect(Collectors.toList());
        }
        return ret;
    }
}
